#include <stddef.h>
#include <GL/glew.h>
#include "../Core/Assert.h"
#include "Texture.h"


static GLenum TranslateFilter(Texture::Filter filter)
{
    switch (filter)
    {
    case Texture::kNearest: return GL_NEAREST;
    case Texture::kLinear: return GL_LINEAR;
    default: Fatal("Invalid filter");
    }

    return GL_NEAREST;
}


Texture::Texture(Format format, size_t width, size_t height, Filter minFilter, Filter magFilter, const void* data)
    : width(width)
    , height(height)
{
    GLenum glFormat = GL_RGBA8;

    switch (format)
    {
    case kRgba8: glFormat = GL_RGBA8; break;
    case kRgba16f: glFormat = GL_RGBA16F; break;
    case kDepthStencil: glFormat = GL_DEPTH_STENCIL; break;
    default: Fatal("Invalid format");
    }

    GLenum glMagFilter = TranslateFilter(magFilter);
    GLenum glMinFilter = TranslateFilter(minFilter);

    glGenTextures(1, &handle);
    glBindTexture(GL_TEXTURE_2D, handle);
    glTexImage2D(GL_TEXTURE_2D, 0, glFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glMinFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glMagFilter);
}


Texture::~Texture()
{
    glDeleteTextures(1, &handle);
}


void BindTexture(const Texture* texture, size_t index)
{
    glActiveTexture(GL_TEXTURE0 + index);
    glBindTexture(GL_TEXTURE_2D, texture->GetHandle());
}
